home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / cross / GBDK-2.0.lha / GBDK / examples / paint.c < prev    next >
C/C++ Source or Header  |  1998-10-05  |  19KB  |  528 lines

  1. #include <gb.h>
  2. #include <drawing.h>
  3.  
  4. #define NB_TOOLS 18
  5. #define NB_DATA_TILES 48
  6.  
  7. #define ARROW 0
  8. #define PEN 1
  9. #define BRUSH 2
  10. #define FILL 3
  11. #define ERASER 4
  12. #define CROSS 5
  13.  
  14. #define UNSELECTED 0
  15. #define SELECTED 1
  16.  
  17. #define FIRST_TOOL 0
  18. #define LAST_TOOL 9
  19. #define FIRST_COLOR 10
  20. #define LAST_COLOR 13
  21. #define FIRST_MODE 14
  22. #define LAST_MODE 17
  23.  
  24. typedef struct icon_info_
  25. {
  26.   UBYTE data_idx; /* Index of data in the data array */
  27.   UBYTE x, y, w, h; /* Position and size (in tiles) */
  28.   UBYTE up, down, left, right; /* Index of next icons (for cursor movements) */
  29.   UBYTE cursor; /* Cursor associated with icon */
  30. } icon_info;
  31.  
  32. typedef struct cursor_info_
  33. {
  34.   UBYTE data_idx; /* Index of data in the data array */
  35.   UBYTE w, h; /* Size (in tiles) */
  36.   UBYTE hot_x, hot_y; /* Position of hot point, relatice to top-left of sprite (in pixels) */
  37. } cursor_info;
  38.  
  39. icon_info icons[] =
  40. {
  41.   /* Pen */
  42.   { 0, 0, 0, 2, 2, 10, 2, 1, 1, 1 }, /* 0 */
  43.   /* Brush */
  44.   { 4, 2, 0, 2, 2, 14, 3, 0, 0, 2 }, /* 1 */
  45.   /* Fill */
  46.   { 8, 0, 2, 2, 2, 0, 4, 3, 3, 3 }, /* 2 */
  47.   /* Eraser */
  48.   { 12, 2, 2, 2, 2, 1, 5, 2, 2, 4 }, /* 3 */
  49.   /* Line */
  50.   { 16, 0, 4, 2, 2, 2, 6, 5, 5, 5 }, /* 4 */
  51.   /* Line */
  52.   { 20, 2, 4, 2, 2, 3, 7, 4, 4, 5 }, /* 5 */
  53.   /* Rectangle */
  54.   { 24, 0, 6, 2, 2, 4, 8, 7, 7, 5 }, /* 6 */
  55.   /* Oval */
  56.   { 28, 2, 6, 2, 2, 5, 9, 6, 6, 5 }, /* 7 */
  57.   /* Filled rectangle */
  58.   { 32, 0, 8, 2, 2, 6, 10, 9, 9, 5 }, /* 8 */
  59.   /* Filled oval */
  60.   { 36, 2, 8, 2, 2, 7, 14, 8, 8, 5 }, /* 9 */
  61.   /* Color */
  62.   { 40, 0, 10, 1, 1, 8, 11, 16, 12, 0 }, /* 10 */
  63.   { 41, 0, 11, 1, 1, 10, 0, 17, 13, 0 }, /* 11 */
  64.   { 42, 1, 10, 1, 1, 8, 13, 10, 14, 0 }, /* 12 */
  65.   { 43, 1, 11, 1, 1, 12, 0, 11, 15, 0 }, /* 13 */
  66.   /* Mode */
  67.   { 44, 2, 10, 1, 1, 9, 15, 12, 16, 0 }, /* 14 */
  68.   { 45, 2, 11, 1, 1, 14, 1, 13, 17, 0 }, /* 15 */
  69.   { 46, 3, 10, 1, 1, 9, 17, 14, 10, 0 }, /* 16 */
  70.   { 47, 3, 11, 1, 1, 16, 1, 15, 11, 0 } /* 17 */
  71. };
  72.  
  73. unsigned char data[NB_DATA_TILES][0x10] =
  74. {
  75.   /* Pen */
  76.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01 },
  77.   { 0x7E,0x02,0x7D,0x05,0x7B,0x0A,0x77,0x14,0x7F,0x18,0x7F,0x27,0x7F,0x00,0x00,0x7F },
  78.   { 0x00,0x00,0xFE,0x01,0xFE,0x0D,0xF6,0x15,0xEE,0x29,0xDE,0x51,0xBE,0xA1,0x7E,0x41 },
  79.   { 0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0x01,0x00,0xFF },
  80.   /* Brush */
  81.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01 },
  82.   { 0x7E,0x02,0x7D,0x0D,0x7F,0x1E,0x7F,0x1E,0x7F,0x1D,0x7F,0x11,0x7F,0x00,0x00,0x7F },
  83.   { 0x00,0x00,0xFE,0x01,0xFE,0x0D,0xF6,0x15,0xEE,0x29,0xDE,0x51,0xBE,0xA1,0x7E,0x41 },
  84.   { 0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0xFD,0xFE,0x01,0x00,0xFF },
  85.   /* Fill */
  86.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01,0x7F,0x02,0x7E,0x0C,0x7D,0x18,0x7E,0x1D },
  87.   { 0x7F,0x1B,0x7F,0x19,0x7F,0x18,0x7F,0x08,0x7F,0x08,0x7F,0x08,0x7F,0x00,0x00,0x7F },
  88.   { 0x00,0x00,0xFE,0x01,0xFE,0x81,0xFE,0x41,0x7E,0x21,0xBE,0x71,0x5E,0xE9,0xAE,0xC5 },
  89.   { 0x5E,0x89,0xBE,0x11,0xFE,0xA1,0xFE,0x41,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x00,0xFF },
  90.   /* Eraser */
  91.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01,0x7E,0x02,0x7C,0x04 },
  92.   { 0x78,0x08,0x7F,0x1F,0x71,0x11,0x7F,0x1F,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F },
  93.   { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xF9,0x1E,0x19,0x2E,0x29,0x5E,0x51 },
  94.   { 0xBE,0xA1,0x7E,0x41,0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x00,0xFF },
  95.   /* Line */
  96.   { 0x00,0x00,0x7F,0x00,0x7F,0x20,0x7F,0x10,0x7F,0x08,0x7F,0x04,0x7F,0x02,0x7F,0x01 },
  97.   { 0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F },
  98.   { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01 },
  99.   { 0xFE,0x81,0xFE,0x41,0xFE,0x21,0xFE,0x11,0xFE,0x09,0xFE,0x05,0xFE,0x01,0x00,0xFF },
  100.   /* Arc */
  101.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x1E,0x7F,0x01,0x7F,0x00,0x7F,0x00,0x7F,0x00 },
  102.   { 0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F },
  103.   { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x81,0xFE,0x41,0xFE,0x21,0xFE,0x11 },
  104.   { 0xFE,0x11,0xFE,0x09,0xFE,0x09,0xFE,0x09,0xFE,0x09,0xFE,0x01,0xFE,0x01,0x00,0xFF },
  105.   /* Rectangle */
  106.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x3F,0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x20 },
  107.   { 0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x3F,0x7F,0x00,0x7F,0x00,0x00,0x7F },
  108.   { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0x05 },
  109.   { 0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0xFD,0xFE,0x01,0xFE,0x01,0x00,0xFF },
  110.   /* Oval */
  111.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x03,0x7F,0x0C,0x7F,0x10,0x7F,0x20,0x7F,0x20 },
  112.   { 0x7F,0x20,0x7F,0x20,0x7F,0x10,0x7F,0x0C,0x7F,0x03,0x7F,0x00,0x7F,0x00,0x00,0x7F },
  113.   { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xC1,0xFE,0x31,0xFE,0x09,0xFE,0x05,0xFE,0x05 },
  114.   { 0xFE,0x05,0xFE,0x05,0xFE,0x09,0xFE,0x31,0xFE,0xC1,0xFE,0x01,0xFE,0x01,0x00,0xFF },
  115.   /* Filled rectangle */
  116.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x3F,0x6A,0x3F,0x75,0x3F,0x6A,0x3F,0x75,0x3F },
  117.   { 0x6A,0x3F,0x75,0x3F,0x6A,0x3F,0x75,0x3F,0x7F,0x3F,0x7F,0x00,0x7F,0x00,0x00,0x7F },
  118.   { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xAE,0xFD,0x56,0xFD,0xAE,0xFD,0x56,0xFD },
  119.   { 0xAE,0xFD,0x56,0xFD,0xAE,0xFD,0x56,0xFD,0xFE,0xFD,0xFE,0x01,0xFE,0x01,0x00,0xFF },
  120.   /* Filled oval */
  121.   { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x03,0x7E,0x0F,0x75,0x1F,0x6A,0x3F,0x75,0x3F },
  122.   { 0x6A,0x3F,0x75,0x3F,0x7A,0x1F,0x7D,0x0F,0x7F,0x03,0x7F,0x00,0x7F,0x00,0x00,0x7F },
  123.   { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xC1,0xBE,0xF1,0x5E,0xF9,0xAE,0xFD,0x56,0xFD },
  124.   { 0xAE,0xFD,0x56,0xFD,0xAE,0xF9,0x7E,0xF1,0xFE,0xC1,0xFE,0x01,0xFE,0x01,0x00,0xFF },
  125.   /* Color */
  126.   { 0x00,0x00,0x7F,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 },
  127.   { 0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x7F,0x7F,0x00,0x7F },
  128.   { 0x00,0x00,0xFE,0xFF,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03 },
  129.   { 0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0x00,0xFF },
  130.   /* Mode */
  131.   { 0x00,0x00,0x7F,0x00,0x7F,0x0C,0x7F,0x10,0x7F,0x08,0x7F,0x04,0x7F,0x18,0x7F,0x00 },
  132.   { 0x7F,0x00,0x7F,0x08,0x7F,0x14,0x7F,0x14,0x7F,0x14,0x7F,0x08,0x7F,0x00,0x00,0x7F },
  133.   { 0x00,0x01,0xFE,0x01,0xFE,0x29,0xFE,0x29,0xFE,0x11,0xFE,0x29,0xFE,0x29,0xFE,0x01 },
  134.   { 0xFE,0x01,0xFE,0x11,0xFE,0x29,0xFE,0x39,0xFE,0x29,0xFE,0x29,0xFE,0x01,0x00,0xFF }
  135. };
  136.  
  137. unsigned char selected_data[NB_DATA_TILES][0x10] =
  138. {
  139.   /* Pen */
  140.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE },
  141.   { 0x81,0xFD,0x82,0xFA,0x84,0xF5,0x88,0xEB,0x80,0xE7,0x80,0xD8,0x80,0xFF,0xFF,0x80 },
  142.   { 0xFF,0xFF,0x01,0xFE,0x01,0xF2,0x09,0xEA,0x11,0xD6,0x21,0xAE,0x41,0x5E,0x81,0xBE },
  143.   { 0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0xFE,0xFF,0x00 },
  144.   /* Brush */
  145.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE },
  146.   { 0x81,0xFD,0x82,0xF2,0x80,0xE1,0x80,0xE1,0x80,0xE2,0x80,0xEE,0x80,0xFF,0xFF,0x80 },
  147.   { 0xFF,0xFF,0x01,0xFE,0x01,0xF2,0x09,0xEA,0x11,0xD6,0x21,0xAE,0x41,0x5E,0x81,0xBE },
  148.   { 0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0x02,0x01,0xFE,0xFF,0x00 },
  149.   /* Fill */
  150.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE,0x80,0xFD,0x81,0xF3,0x82,0xE7,0x81,0xE2 },
  151.   { 0x80,0xE4,0x80,0xE7,0x80,0xE7,0x80,0xF7,0x80,0xF7,0x80,0xF7,0x80,0xFF,0xFF,0x80 },
  152.   { 0xFF,0xFF,0x01,0xFE,0x01,0x7E,0x01,0xBE,0x81,0xDE,0x41,0x8E,0xA1,0x16,0x51,0x3A },
  153.   { 0xA1,0x76,0x41,0xEE,0x01,0x5E,0x01,0xBE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFF,0x00 },
  154.   /* Eraser */
  155.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE,0x81,0xFD,0x83,0xFB },
  156.   { 0x87,0xF7,0x80,0xE0,0x8E,0xEE,0x80,0xE0,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 },
  157.   { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x06,0xE1,0xE6,0xD1,0xD6,0xA1,0xAE },
  158.   { 0x41,0x5E,0x81,0xBE,0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFF,0x00 },
  159.   /* Line */
  160.   { 0xFF,0xFF,0x80,0xFF,0x80,0xDF,0x80,0xEF,0x80,0xF7,0x80,0xFB,0x80,0xFD,0x80,0xFE },
  161.   { 0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 },
  162.   { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE },
  163.   { 0x01,0x7E,0x01,0xBE,0x01,0xDE,0x01,0xEE,0x01,0xF6,0x01,0xFA,0x01,0xFE,0xFF,0x00 },
  164.   /* Arc */
  165.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xE1,0x80,0xFE,0x80,0xFF,0x80,0xFF,0x80,0xFF },
  166.   { 0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 },
  167.   { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x7E,0x01,0xBE,0x01,0xDE,0x01,0xEE },
  168.   { 0x01,0xEE,0x01,0xF6,0x01,0xF6,0x01,0xF6,0x01,0xF6,0x01,0xFE,0x01,0xFE,0xFF,0x00 },
  169.   /* Rectangle */
  170.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xC0,0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xDF },
  171.   { 0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xC0,0x80,0xFF,0x80,0xFF,0xFF,0x80 },
  172.   { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0xFA },
  173.   { 0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0x02,0x01,0xFE,0x01,0xFE,0xFF,0x00 },
  174.   /* Oval */
  175.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFC,0x80,0xF3,0x80,0xEF,0x80,0xDF,0x80,0xDF },
  176.   { 0x80,0xDF,0x80,0xDF,0x80,0xEF,0x80,0xF3,0x80,0xFC,0x80,0xFF,0x80,0xFF,0xFF,0x80 },
  177.   { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x3E,0x01,0xCE,0x01,0xF6,0x01,0xFA,0x01,0xFA },
  178.   { 0x01,0xFA,0x01,0xFA,0x01,0xF6,0x01,0xCE,0x01,0x3E,0x01,0xFE,0x01,0xFE,0xFF,0x00 },
  179.   /* Filled rectangle */
  180.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0 },
  181.   { 0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x80,0xC0,0x80,0xFF,0x80,0xFF,0xFF,0x80 },
  182.   { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02 },
  183.   { 0xF9,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02,0x01,0x02,0x01,0xFE,0x01,0xFE,0xFF,0x00 },
  184.   /* Filled oval */
  185.   { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFC,0x83,0xF0,0x8F,0xE0,0x9F,0xC0,0x9F,0xC0 },
  186.   { 0x9F,0xC0,0x9F,0xC0,0x8F,0xE0,0x83,0xF0,0x80,0xFC,0x80,0xFF,0x80,0xFF,0xFF,0x80 },
  187.   { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x3E,0xC1,0x0E,0xF1,0x06,0xF9,0x02,0xF9,0x02 },
  188.   { 0xF9,0x02,0xF9,0x02,0xF1,0x06,0xC1,0x0E,0x01,0x3E,0x01,0xFE,0x01,0xFE,0xFF,0x00 },
  189.   /* Color */
  190.   { 0x00,0x00,0x7F,0x7F,0x61,0x61,0x52,0x52,0x4C,0x4C,0x4C,0x4C,0x52,0x52,0x61,0x61 },
  191.   { 0x40,0x5E,0x40,0x6D,0x40,0x73,0x40,0x73,0x40,0x6D,0x40,0x5E,0x7F,0x7F,0x00,0x7F },
  192.   { 0x00,0x00,0xFE,0xFF,0xFE,0x87,0xFE,0x4B,0xFE,0x33,0xFE,0x33,0xFE,0x4B,0xFE,0x87 },
  193.   { 0x7A,0x7B,0xB6,0xB7,0xCE,0xCF,0xCE,0xCF,0xB6,0xB7,0x7A,0x7B,0xFE,0xFF,0x00,0xFF },
  194.   /* Mode */
  195.   { 0x00,0x00,0x7F,0x7F,0x73,0x73,0x6F,0x6F,0x77,0x77,0x7B,0x7B,0x67,0x67,0x7F,0x7F },
  196.   { 0x7F,0x7F,0x77,0x77,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x77,0x77,0x7F,0x7F,0x00,0x7F },
  197.   { 0x00,0x01,0xFE,0xFF,0xD6,0xD7,0xD6,0xD7,0xEE,0xEF,0xD6,0xD7,0xD6,0xD7,0xFE,0xFF },
  198.   { 0xFE,0xFF,0xEE,0xEF,0xD6,0xD7,0xC6,0xC7,0xD6,0xD7,0xD6,0xD7,0xFE,0xFF,0x00,0xFF }
  199. };
  200.  
  201. cursor_info cursors[] =
  202. {
  203.   /* Arrow */
  204.   { 0, 1, 1, 0, 0 },
  205.   /* Pen */
  206.   { 1, 2, 2, 0, 15 },
  207.   /* Brush */
  208.   { 5, 2, 2, 0, 15 },
  209.   /* Fill */
  210.   { 9, 2, 2, 2, 15 },
  211.   /* Eraser */
  212.   { 13, 2, 2, 0, 15 },
  213.   /* Cross */
  214.   { 17, 2, 2, 5, 10 }
  215. };
  216.  
  217. unsigned char cursors_data[][0x10] = {
  218.   /* Arrow */
  219.   { 0xFF,0x00,0xFF,0x7E,0xFF,0x7C,0xFE,0x78,0xFF,0x7C,0xFF,0x6E,0xFF,0x46,0xEF,0x00 },
  220.   /* Pen */
  221.   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x01 },
  222.   { 0x0F,0x02,0x1F,0x05,0x3F,0x0A,0x7F,0x14,0x7E,0x28,0xFC,0x30,0xF8,0x40,0x60,0x00 },
  223.   { 0x00,0x00,0x00,0x00,0x3C,0x00,0x7C,0x18,0xFC,0x28,0xFC,0x50,0xF8,0xA0,0xF0,0x40 },
  224.   { 0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
  225.   /* Brush */
  226.   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x01,0x0F,0x02 },
  227.   { 0x1F,0x05,0x7F,0x0A,0xFF,0x34,0xFE,0x78,0xFC,0x78,0xFC,0x70,0xF8,0x40,0x60,0x00 },
  228.   { 0x00,0x00,0x00,0x00,0x78,0x00,0xF8,0x30,0xF8,0x50,0xF8,0xA0,0xF0,0x40,0xE0,0x80 },
  229.   { 0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
  230.   /* Fill */
  231.   { 0x00,0x00,0x00,0x00,0x07,0x00,0x0F,0x02,0x1F,0x05,0x7F,0x08,0xFE,0x31,0xFD,0x63 },
  232.   { 0xFA,0x77,0xFD,0x6E,0xFF,0x64,0xFF,0x62,0xF7,0x21,0x73,0x20,0x70,0x20,0x50,0x00 },
  233.   { 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xC0,0x00,0xE0,0x80,0xF0,0xC0,0x78,0xA0 },
  234.   { 0xF8,0x10,0xF8,0x20,0xF0,0x40,0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00 },
  235.   /* Eraser */
  236.   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0F,0x03 },
  237.   { 0x1F,0x04,0x3F,0x08,0x7F,0x11,0xFF,0x22,0xFF,0x7D,0xFF,0x46,0xFF,0x7C,0x7E,0x00 },
  238.   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xF0,0xE0 },
  239.   { 0xF0,0x60,0xF0,0xA0,0xF0,0x40,0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00 },
  240.   /* Cross */
  241.   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x04,0x0E,0x04 },
  242.   { 0x0E,0x04,0xFF,0x04,0xFB,0x7B,0xFF,0x04,0x0E,0x04,0x0E,0x04,0x0E,0x04,0x0E,0x00 },
  243.   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
  244.   { 0x00,0x00,0xE0,0x00,0xE0,0xC0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
  245. };
  246.  
  247. unsigned char data_buffer[NB_DATA_TILES][0x10];
  248.  
  249. UBYTE colors[] = { WHITE, DKGREY, LTGREY, BLACK };
  250. UBYTE modes[] = { SOLID, OR, XOR, AND };
  251.  
  252. UBYTE current_tool;
  253. UBYTE current_color;
  254. UBYTE current_mode;
  255. UBYTE current_cursor;
  256. UBYTE menu_cursor_pos;
  257.  
  258. UBYTE cursor_x;
  259. UBYTE cursor_y;
  260.  
  261. void set_cursor()
  262. {
  263.   UBYTE x, y, i;
  264.  
  265.   i = 0;
  266.   for(x = 0; x < cursors[current_cursor].w; x++)
  267.     for(y = 0; y < cursors[current_cursor].h; y++) {
  268.       set_sprite_data(i,
  269.               1,
  270.               cursors_data[cursors[current_cursor].data_idx+i]);
  271.       set_sprite_tile(i, i);
  272.       set_sprite_prop(i, 0x10);
  273.       i++;
  274.     }
  275.   /* Hide unused sprites */
  276.   for(; i < 4; i++) {
  277.     move_sprite(i, 0, 0);
  278.   }
  279. }
  280.  
  281. void move_cursor()
  282. {
  283.   UBYTE x, y;
  284.  
  285.   for(x = 0; x < cursors[current_cursor].w; x++)
  286.     for(y = 0; y < cursors[current_cursor].h; y++)
  287.       move_sprite((x<<1)+y,
  288.           cursor_x+8 - cursors[current_cursor].hot_x + (x<<3),
  289.           cursor_y+16 - cursors[current_cursor].hot_y + (y<<3));
  290. }
  291.  
  292. void move_menu_cursor()
  293. {
  294.   move_sprite(0,
  295.           ((icons[menu_cursor_pos].x+icons[menu_cursor_pos].w)<<3) + 4,
  296.           ((icons[menu_cursor_pos].y+icons[menu_cursor_pos].h)<<3) + 12);
  297. }
  298.  
  299. void set_icon(UBYTE icon, UBYTE selected)
  300. {
  301.   UBYTE x, y;
  302.  
  303.   for(x = 0; x < icons[icon].w; x++)
  304.     for(y = 0; y < icons[icon].h; y++)
  305.       switch_data(icons[icon].x + x,
  306.           icons[icon].y + y,
  307.           (selected ?
  308.            selected_data[icons[icon].data_idx+(x<<1)+y] :
  309.            data[icons[icon].data_idx+(x<<1)+y]),
  310.           data_buffer[icons[icon].data_idx+(x<<1)+y]);
  311. }
  312.  
  313. void change_icon(UBYTE icon, UBYTE selected)
  314. {
  315.   UBYTE x, y;
  316.  
  317.   for(x = 0; x < icons[icon].w; x++)
  318.     for(y = 0; y < icons[icon].h; y++)
  319.       switch_data(icons[icon].x + x,
  320.           icons[icon].y + y,
  321.           (selected ?
  322.            selected_data[icons[icon].data_idx+(x<<1)+y] :
  323.            data[icons[icon].data_idx+(x<<1)+y]),
  324.           NULL);
  325. }
  326.  
  327. void reset_icon(UBYTE icon)
  328. {
  329.   UBYTE x, y;
  330.  
  331.   for(x = 0; x < icons[icon].w; x++)
  332.     for(y = 0; y < icons[icon].h; y++)
  333.       switch_data(icons[icon].x + x,
  334.           icons[icon].y + y,
  335.           data_buffer[icons[icon].data_idx+(x<<1)+y],
  336.           NULL);
  337. }
  338.  
  339. void splash()
  340. {
  341.   UBYTE x, y;
  342.  
  343.   cursor_x = 40;
  344.   cursor_y = 50;
  345.   current_cursor = PEN;
  346.   set_cursor();
  347.   move_cursor();
  348.   SHOW_SPRITES;
  349.  
  350.   for(; cursor_x < 120; cursor_x++) {
  351.     wait_vbl_done();
  352.     move_cursor();
  353.     plot(cursor_x, cursor_y, BLACK, SOLID);
  354.   }
  355.   for(; cursor_y < 94; cursor_y++) {
  356.     wait_vbl_done();
  357.     move_cursor();
  358.     plot(cursor_x, cursor_y, BLACK, SOLID);
  359.   }
  360.   for(; cursor_x > 40; cursor_x--) {
  361.     wait_vbl_done();
  362.     move_cursor();
  363.     plot(cursor_x, cursor_y, BLACK, SOLID);
  364.   }
  365.   for(; cursor_y > 50; cursor_y--) {
  366.     wait_vbl_done();
  367.     move_cursor();
  368.     plot(cursor_x, cursor_y, BLACK, SOLID);
  369.   }
  370.   cursor_x = 160/2;
  371.   cursor_y = 144/2;
  372.   current_cursor = FILL;
  373.   set_cursor();
  374.   move_cursor();
  375.  
  376.   for(y = 51; y < 94; y++)
  377.     for(x = 41; x < 120; x++)
  378.       plot(x, y, LTGREY, SOLID);
  379.  
  380.   HIDE_SPRITES;
  381. }
  382.  
  383. void menu()
  384. {
  385.   UBYTE i, key;
  386.   UBYTE slowdown;
  387.   UBYTE cursor;
  388.  
  389.   slowdown = 50;
  390.  
  391.   for(i = 0; i < NB_TOOLS; i++)
  392.     set_icon(i,
  393.          i == FIRST_TOOL + current_tool ||
  394.          i == FIRST_COLOR + current_color ||
  395.          i == FIRST_MODE + current_mode);
  396.  
  397.   cursor = current_cursor;
  398.   current_cursor = ARROW;
  399.   set_cursor();
  400.   move_menu_cursor();
  401.   SHOW_SPRITES;
  402.   waitpadup();
  403.   do {
  404.     wait_vbl_done();
  405.     key = joypad();
  406.     if(key & (J_UP|J_DOWN|J_LEFT|J_RIGHT)) {
  407.       if(key & J_UP)
  408.     menu_cursor_pos = icons[menu_cursor_pos].up;
  409.       if(key & J_DOWN)
  410.     menu_cursor_pos = icons[menu_cursor_pos].down;
  411.       if(key & J_LEFT)
  412.     menu_cursor_pos = icons[menu_cursor_pos].left;
  413.       if(key & J_RIGHT)
  414.     menu_cursor_pos = icons[menu_cursor_pos].right;
  415.       move_menu_cursor();
  416.       while(slowdown && key == joypad()) {
  417.     wait_vbl_done();
  418.     slowdown--;
  419.       }
  420.       slowdown = 10;
  421.     } else
  422.       slowdown = 50;
  423.     if(key & J_A) {
  424.       if( /* menu_cursor_pos >= FIRST_TOOL && */ menu_cursor_pos <= LAST_TOOL) {
  425.     if(menu_cursor_pos != /* FIRST_TOOL + */ current_tool) {
  426.       change_icon(/* FIRST_TOOL + */ current_tool, UNSELECTED);
  427.       current_tool = menu_cursor_pos /* - FIRST_TOOL */;
  428.       change_icon(/* FIRST_TOOL + */ current_tool, SELECTED);
  429.       cursor = icons[/* FIRST_TOOL + */ current_tool].cursor;
  430.     }
  431.       } else if(menu_cursor_pos >= FIRST_COLOR && menu_cursor_pos <= LAST_COLOR) {
  432.     if(menu_cursor_pos != FIRST_COLOR + current_color) {
  433.       change_icon(FIRST_COLOR + current_color, UNSELECTED);
  434.       current_color = menu_cursor_pos - FIRST_COLOR;
  435.       change_icon(FIRST_COLOR + current_color, SELECTED);
  436.     }
  437.       } else if(menu_cursor_pos >= FIRST_MODE && menu_cursor_pos <= LAST_MODE) {
  438.     if(menu_cursor_pos != FIRST_MODE + current_mode) {
  439.       change_icon(FIRST_MODE + current_mode, UNSELECTED);
  440.       current_mode = menu_cursor_pos - FIRST_MODE;
  441.       change_icon(FIRST_MODE + current_mode, SELECTED);
  442.     }
  443.       }
  444.     }
  445.   } while(key != J_SELECT);
  446.   waitpadup();
  447.   for(i = 0; i < NB_TOOLS; i++)
  448.     reset_icon(i);
  449.   HIDE_SPRITES;
  450.   current_cursor = cursor;
  451. }
  452.  
  453. void run()
  454. {
  455.   UBYTE key;
  456.   UBYTE slowdown;
  457.   UBYTE drawn, erased;
  458.  
  459.   slowdown = 10;
  460.   drawn = erased = 0;
  461.  
  462.   set_cursor();
  463.   move_cursor();
  464.   SHOW_SPRITES;
  465.  
  466.   while(1) {
  467.     wait_vbl_done();
  468.     key = joypad();
  469.     if(key & (J_UP|J_DOWN|J_LEFT|J_RIGHT)) {
  470.       if(key & J_UP && cursor_y > 0)
  471.     cursor_y--;
  472.       if(key & J_DOWN && cursor_y < 143)
  473.     cursor_y++;
  474.       if(key & J_LEFT && cursor_x > 0)
  475.     cursor_x--;
  476.       if(key & J_RIGHT && cursor_x < 159)
  477.     cursor_x++;
  478.       move_cursor();
  479.       while(slowdown && key == joypad()) {
  480.     wait_vbl_done();
  481.     slowdown--;
  482.       }
  483.       slowdown = 1;
  484.       drawn = erased = 0;
  485.     } else
  486.       slowdown = 10;
  487.     if(key & J_SELECT) {
  488.       HIDE_SPRITES;
  489.       menu();
  490.       set_cursor();
  491.       move_cursor();
  492.       SHOW_SPRITES;
  493.     }
  494.     if((key & (J_A|J_B)) == J_A) {
  495.       if(!drawn) {
  496.     drawn++;
  497.     plot(cursor_x, cursor_y, colors[current_color], modes[current_mode]);
  498.       }
  499.     } else
  500.       drawn = 0;
  501.     if((key & (J_A|J_B)) == J_B) {
  502.       if(!erased) {
  503.     erased++;
  504.     plot(cursor_x, cursor_y, WHITE, SOLID);
  505.       }
  506.     } else
  507.       erased = 0;
  508.   }
  509. }
  510.  
  511. void main()
  512. {
  513.   /* Initialize sprite palette */
  514.   OBP1_REG = 0xE0U;
  515.  
  516.   splash();
  517.  
  518.   current_tool = 0;
  519.   current_color = BLACK;
  520.   current_mode = SOLID;
  521.   current_cursor = PEN;
  522.   menu_cursor_pos = 0;
  523.   cursor_x = 160/2;
  524.   cursor_y = 144/2;
  525.  
  526.   run();
  527. }
  528.